<?php
    require_once("../classes/cas.php");
    class GaussPivotamento
    {
        private $biblioteca_xml;
        private $sistemas;
        private $dimensao;
        private $arquivo;
        public function __construct($arquivo)
        {
            $this->biblioteca_xml = "/home/projetos/anaweb/anaweb-new/bibliotecas/bib_demo.xml";
            $this->getSystems();
            $this->arquivo = $arquivo;
        }
        public function mostraFormularioProblemas()
        {
?>
        <form name="formulario" action="gauss.php" method="get">
            <p>Selecione uma matriz para testar o programa: 
            <select name="indice" onchange="formulario.submit()">
<?php
            $this->createMenu();
?>
            </select>
            </p>
        </form>
<?php
        }
        private function createMenu() {
            for($i = 0; $i < sizeof($this->sistemas); $i++) {
?>
                <option value="<?php echo $i ?>" <?php if ($i == @$_GET['indice']) echo " selected"; ?>>matriz (<?php echo ($i+1) ?>) (dim <?php echo $this->getDim($i) ?>)</option>
<?php
            }
        }
        private function getSystems() {
            $objeto = DOMDocument::load($this->biblioteca_xml);
            $filho = $objeto->getelementsbytagname("lin_systems");
            if ($filho->length > 0) {
                $temp = $filho->item(0)->getelementsbytagname("system");
                $j = 0;
                for($i = 0; $i < $temp->length; $i++) {
                    $method = $temp->item($i)->getelementsbytagname("method");
                    if ($method->item(0)->nodeValue == 'direct') {
                        $this->sistemas[$j] = $temp->item($i);
                        $j++;
                    }
                }
            }
        }
        public function getDim($indice) {
            $dimensao = $this->sistemas[$indice]->getelementsbytagname("dim");
            $dim = $dimensao->item(0)->nodeValue;
            return $dim;
        }
        public function getMatrix($indice) {
            $linhas = $this->sistemas[$indice]->getelementsbytagname("row");
            for($i = 0; $i < $linhas->length; $i++) {
                $x = $linhas->item($i)->getelementsbytagname("x");
                for($j = 0; $j < $x->length; $j++) {
                    $A[$i][$j] = $x->item($j)->nodeValue;
                }
            }
            return $A;
        }
        public function execScilab($A)
        {
            echo "        <p><strong>Resultado pelo Scilab:</strong><br>";
            $scilab = new CAS();
            $scilab->loadMatrix($A, "A");
            $scilab->addParam("getf('".$this->arquivo."')");
            $scilab->addParam("l = size(A,'r')");
            $scilab->addParam($_SESSION['CORRECAO']->getFuncao()."( A(:,1:l), A(:,l+1) )");
            $scilab->exec();
            echo $scilab->getgauss();
            echo "<br><a href=\"javascript:showhide('scilab')\">Verificar execu&ccedil;&atilde;o</a>";
            echo "<div id=\"scilab\">";
            $scilab->disp();
            echo "</div>";
            echo "</p>\n";
        }
        public function execAnaweb($A,$dim)
        {
            $saida = "<p>Matriz inicial:<br>";
            $saida .= "<table border=\"0\">";
            for ($i = 0; $i < $dim; $i++)
            {
                $saida.= "<tr>";
                for ($j = 0; $j <= $dim; $j++)
                {
                    $saida.= "<td valign=\"top\" align=\"center\" width=\"50\">".(round($A[$i][$j],2))."</td>";
                } //end for j
                $saida.= "</tr>";
            } //end for i
            $saida.= "</table></p>";

            $saida.= "<br>Iniciando triangulariza&ccedil;&atilde;o<br>";
            for ($k = 0; $k < $dim-1; $k++)
            {
                /*** Troca de linhas, caso exista algum elemento de valor absoluto
                    abaixo da diagonal principal na mesma coluna da diagonal principal ****/
                $maior = abs($A[$k][$k]);
                $indice = $k;

                /*** Verificando o valor absoluto dos elementos abaixo da diagonal ***/
                for ($cont = $k+1; $cont < $dim; $cont++)
                {
                    if (abs($A[$cont][$k]) > $maior)
                    {
                        $maior = abs($A[$cont][$k]);
                        $indice = $cont;
                    }
                }


                /*** Troca das linha ***/
                if ($indice != $k) {
                    for ($l = 0; $l <= $dim; $l++)
                    {
                        //troca de linha
                        $aux2 = $A[$k][$l];
                        @$A[$k][$l] = $A[$indice][$l];
                        $A[$indice][$l] = $aux2;
                    }
                    $saida.= "<p>Troca da linha ".($k+1)." pela linha ".($indice+1).":<br>";
                    $saida.= "<table>";
                    for ($i = 0; $i < $dim; $i++)
                    {
                        $saida.= "<tr>";
                        for ($j = 0; $j <= $dim; $j++)
                        {
                            $saida.= "<td width=\"50\" align=\"center\">".round($A[$i][$j],2)."</td>";
                        }
                        $saida.= "</tr>";
                    }
                    $saida.= "</table></p>";
                }
                /*** Fim da troca ***/
            
                /*** Zerando elementos abaixo da diagonal principal ***/
                for ($i = $k+1; $i < $dim; $i++)
                {
                    @$M[$i][$k] = -$A[$i][$k]/$A[$k][$k];
                    for ($j = 0; $j < $dim+1; $j++)
                        $A[$i][$j] += $M[$i][$k] * $A[$k][$j];
                } // end fori
            
                $aux2 = $k+1;
                $saida.= "<p>Zerando elementos abaixo da diagonal:<br>";
                $saida.= "<table border=\"0\">";
                for ($i = 0; $i < $dim; $i++)
                {
                    $aux = $i+1;
                    $saida.= "<tr>";
                    for ($j = 0; $j <= $dim; $j++)
                    {
                        $saida.= "<td align=\"center\" valign=\"top\" width=\"50\">".round($A[$i][$j], 2)."</td>";
                    } //end for j2
                    if ($i < $k+1) $saida.= "<td>&nbsp;</td>";
                    else
                    {
                        $saida.= "<td>L<sub>".($aux)."</sub> = L<sub>".($aux);
                        $saida.= "</sub> - [(a<sub>$aux$aux2</sub>/a<sub>$aux2$aux2</sub>)";
                        $saida.= "</sub> * L<sub>$aux2</sub>]";
                        $saida.= "</td>";
                    } //end if
                    $saida.= "</tr>";
                } //end for i2
                $saida.= "</table></p>";
            } // end fork
            $saida.= "<p>Triangulariza&ccedil;&atilde;o finalizada:<br>";
            $saida.= "<table border=\"0\">";
            for ($i = 0; $i < $dim; $i++)
            {
                $saida.= "<tr>\n";
                for ($j = 0; $j < $dim; $j++)
                {
                    $aux = $j+1;
                    if ($j > 0)
                    {
                        $saida.= "<td valign=\"top\" align=\"center\" width=\"20\"> + </td>";
                    } //end ifj
                    $saida.= "<td align=\"right\" valign=\"top\">".round($A[$i][$j], 2)."</td>";
                    $saida.= "<td align=\"right\" valign=\"top\">x<sub>".$aux."</sub></td>";
                } //end forj
                $saida.= "<td valign=\"top\" align=\"center\" width=\"20\"> = </td>";
                $saida.= "<td valign=\"top\" align=\"right\">".round($A[$i][$dim], 2)."</td>";
                $saida.= "\n</tr>\n";
            } //end fori
            $saida.= "</table></p>";
            
            
            /*** retrossubstituicao ***/
            for ($k = $dim-1; $k >= 0; $k--)
            {
                $VetX[$k] = $A[$k][$dim];
                for ($i = $k+1; $i < $dim; $i++)
                {
                    //linha 240
                    $VetX[$k] -= $A[$k][$i] * $VetX[$i];
                } // end for
                if ($A[$k][$k] == 0)
                {
                    // pivo se anulou
                    if ($VetX[$k] == 0)
                    {
                        // infinitas solucoes (0 x = 0)
                        //echo GAUSS_MSG_19;
                        $res = "infinitas";
                        $VetX[$k] = 1;
                    }
                    else
                    {
                        // nao possui solucao (0 x = a)
                        //echo GAUSS_MSG_20;
                        $res = "sem sol";
                        break;
                    }
                }
                else
                {
                    // possui nica solucao
                    $VetX[$k] /= $A[$k][$k];
                }
            } // end for1
            $VetX = array_reverse($VetX);
            echo "        <p><strong>Resultado pelo ANAWEB:</strong><br> ";
            if (!isset($res))
            {
                foreach ($VetX as $v)
                    $s=@$s.", $v";
                echo "(".substr($s,2).")<sup>T</sup>\n";
            }
            elseif ($res == "infinitas")
            {
                echo "infinitas solucoes\n";
            }
            else
            {
                echo "sem solucao\n";
            }
            echo "<br><a href=\"javascript:showhide('anaweb')\">Verificar execu&ccedil;&atilde;o</a>";
            echo "<div id=\"anaweb\">";
            echo $saida;
            echo "</div>";
            echo "</p>";
        }
    }
?>
